﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.IO;
using BesAsm.Stormwater.HspfCore;
using BesAsm.Framework.Reporting;

namespace BesAsm.Stormwater.HspfResults
{
  public abstract class LandSegmentResults : List<L61Block>, ILandSegment, IMessenger
  {
    LandSegment _segment;

    private LandSegmentResults()
      :base()
    {
      MessageQueue.AddMessenger(this);
    }

    protected LandSegmentResults(LandSegment segment)
      : this()
    {
      _segment = segment;
    }

    protected LandSegmentResults(int segmentNum, string segmentName)
      : this()
    {
      _segment = new LandSegment(segmentNum, segmentName, this.Type);
    }

    public abstract DataTable GetDataTable();

    public void WriteResults(string file)
    {
      StreamWriter writer = new StreamWriter(file);

      Dictionary<string, object> resultsArray = this[0].GetResultsDictionary();

      writer.WriteLine(
        BuildCsvString(resultsArray.Count), 
        resultsArray.Keys.ToArray());

      foreach (L61Block block in this)
      {
        resultsArray = block.GetResultsDictionary();
        writer.WriteLine(
          BuildCsvString(resultsArray.Count), 
          resultsArray.Values.ToArray());
      }
      writer.Close();
      ReportMessage("Wrote .csv file '" + file + "'", ReportableMessageType.Info);
    }

    public string BuildCsvString(int count)
    {
      string s = string.Empty;

      for (int i = 0; i < count; i++)
        s += "{" + i + "},";

      s = s.TrimEnd(new char[] { ',' });
      return s;

    }

    #region ILandSegment Members

    public abstract SegmentType Type { get; }

    public int SegmentNumber
    {
      get
      {
        return _segment.SegmentNumber;
      }
      set
      {
        _segment.SegmentNumber = value;
      }
    }

    public string Name
    {
      get
      {
        return _segment.Name;
      }
      set
      {
        _segment.Name = value;
      }
    }

    public double Area
    {
      get { return _segment.Area; }
      set { _segment.Area = value; }
    }

    #endregion

    #region IMessenger Members

    public event MessageReportedEventHandler MessageReported;

    /// <summary>
    /// Called when a message is to be reported.
    /// </summary>
    /// <param name="e">The message to report</param>
    protected void OnMessageReported(MessageReportedArgs e)
    {
      if (MessageReported != null)
        MessageReported(this, e);
    }

    protected void ReportMessage(string message, ReportableMessageType type)
    {
      ReportableMessage rm = new ReportableMessage()
      {
        MessageType = type,
        Description = message
      };
      OnMessageReported(new MessageReportedArgs(rm));
    }

    #endregion

  }
}
